package net.cnki.sunny.service.impl;

import cn.hutool.core.date.DateUtil;
import net.cnki.sunny.base.BaseRepository;
import net.cnki.sunny.model.vo.*;
import net.cnki.sunny.model.dto.DataDTO;
import net.cnki.sunny.service.DataService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class DataServiceImpl extends BaseRepository implements DataService {

    public List<Map<String, String>> getList() {
        String sql = "SELECT title,content,url,type,pubdate,website FROM TEXTDATAVIEW";
        return this.context.excuteQueryList(sql).stream().map(s -> {
            String type = s.get("type");
            if (ObjectUtils.isEmpty(type)) {
                return s;
            }
            String typeArr[] = type.split(";");
            StringBuffer typeCondition = new StringBuffer();
            for (int i = 0; i < typeArr.length; i++) {
                if (i > 0) {
                    typeCondition.append("and");
                }
                typeCondition.append("id = " + typeArr[i]);

            }
            String typeSql = "select id,themename from EPM_THEME where " + typeCondition;
            ThemeVO themeVO = this.context.excuteQueryReturnOne(typeSql, ThemeVO.class);
            s.put("themeName", themeVO.getThemename());
            return s;
        }).collect(Collectors.toList());
    }

    @Override
    public List<Map<String, String>> selectListByCondition(DataDTO dataDTO) {
        String sql = "SELECT id,urlid,title,content,url,type,pubdate,website,digest FROM TEXTDATAVIEW where ";
        StringBuffer sqlCondition = new StringBuffer("type = " + dataDTO.getType());
        if (StringUtils.hasLength(dataDTO.getKeywords())) {
            sqlCondition.append(" and title %= " + dataDTO.getKeywords());
        }
        Optional.ofNullable(dataDTO.getStartTime()).ifPresent(s -> sqlCondition.append(" and pubdate >= '" + DateUtil.formatDate(s) + "'"));
        Optional.ofNullable(dataDTO.getEndTime()).ifPresent(s -> sqlCondition.append(" and pubdate < '" + DateUtil.formatDate(s) + "'"));
        sqlCondition.append(" order by finddate desc ");
        if (StringUtils.hasLength(dataDTO.getOrderField()) && StringUtils.hasLength(dataDTO.getOrderType())) {
            sqlCondition.append(" , " + dataDTO.getOrderField() + (dataDTO.getOrderType().equals("1") ? " asc" : " desc"));
        }
        if (!ObjectUtils.isEmpty(dataDTO.getPageNum()) && !ObjectUtils.isEmpty(dataDTO.getPageSize())) {
            sqlCondition.append(" limit " + (dataDTO.getPageNum() - 1) * dataDTO.getPageSize() + "," + dataDTO.getPageSize());
        }
        return this.context.excuteQueryList(sql + sqlCondition);
    }

    public List<ThemeTreeVO> selectThemeList() {
        return selectChildThemeList("0", 10);
    }

    public List<ThemeTreeVO> selectFirstThemeList() {
        return selectChildThemeList("0", 0);
    }

    public List<ThemeTreeVO> selectChildThemeList(String parentid, Integer level) {
        Integer curLevel = 0;
        String sql = "select id,themename,parentid from EPM_THEME where parentid = " + parentid;
        List<ThemeTreeVO> treeVOList = this.context.excuteQuery(sql, ThemeTreeVO.class);
        if (level > curLevel) {
            curLevel++;
            for (ThemeTreeVO treeVO : treeVOList) {
                treeVO.setChildList(selectChildThemeList(treeVO.getId(), level));
            }
        }
        return treeVOList;
    }

    public List<ThemeVO> selectLeafThemeList(String parentid) {
        List<ThemeVO> themeVOList = new ArrayList<>();
        String sql = "select id,themename,parentid from EPM_THEME where parentid = " + parentid;
        List<ThemeVO> treeVOList = this.context.excuteQuery(sql, ThemeVO.class);
        if (CollectionUtils.isEmpty(treeVOList)) {
            themeVOList.add(this.context.excuteQueryReturnOne("select id,themename,parentid from EPM_THEME where id = " + parentid, ThemeVO.class));
        }
        for (ThemeVO themeVO : treeVOList) {
            themeVOList.addAll(selectLeafThemeList(themeVO.getId()));
        }
        return themeVOList;
    }

    @Override
    public DataVO selectLeafThemeDataList(DataDTO dataDTO) {
        DataVO dataVO = new DataVO();
        if (ObjectUtils.isEmpty(dataDTO.getType())) {
            dataDTO.setType("0");
        }
        List<ThemeVO> themeVOList = selectLeafThemeList(dataDTO.getType());
        String sql = "SELECT id,urlid,title,content,url,type,pubdate,website,digest FROM TEXTDATAVIEW where ";
        StringBuffer sqlCondition = new StringBuffer();
        for (ThemeVO themeVO : themeVOList) {
            if (sqlCondition.length() > 0) {
                sqlCondition.append(" or ");
            }
            sqlCondition.append("type= " + themeVO.getId());
        }
        if (sqlCondition.length() > 0) {
            sqlCondition.insert(0, "(").append(")");
        }
        if (StringUtils.hasLength(dataDTO.getKeywords())) {
            sqlCondition.append(" and title %= " + dataDTO.getKeywords());
        }
        Optional.ofNullable(dataDTO.getStartTime()).ifPresent(s -> sqlCondition.append(" and pubdate >= '" + DateUtil.formatDate(s) + "'"));
        Optional.ofNullable(dataDTO.getEndTime()).ifPresent(s -> sqlCondition.append(" and pubdate < '" + DateUtil.formatDate(s) + "'"));
        dataVO.setTotalCount(this.context.excuteQueryRecordNumber("select count(*) from TEXTDATAVIEW where " + sqlCondition));
        sqlCondition.append(" order by finddate desc ");
        if (StringUtils.hasLength(dataDTO.getOrderField()) && StringUtils.hasLength(dataDTO.getOrderType())) {
            sqlCondition.append(" , " + dataDTO.getOrderField() + (dataDTO.getOrderType().equals("1") ? " asc" : " desc"));
        }
        if (!ObjectUtils.isEmpty(dataDTO.getPageNum()) && !ObjectUtils.isEmpty(dataDTO.getPageSize())) {
            sqlCondition.append(" limit " + (dataDTO.getPageNum() - 1) * dataDTO.getPageSize() + "," + dataDTO.getPageSize());
        }
        dataVO.setDataList(this.context.excuteQueryList(sql + sqlCondition));
        return dataVO;
    }

    @Override
    public DataVO getSearchData(DataDTO dataDTO) {
        DataVO dataVO = selectLeafThemeDataList(dataDTO);
        List<ThemeTreeVO> treeVOList = selectThemeList();
        dataVO.setThemeTreeList(treeVOList);
        return dataVO;
    }


    public List<DataTreeVO> selectChildThemeDataList(DataDTO dataDTO, String parentid) {
        String sql = "select id,themename,parentid from EPM_THEME where parentid = " + parentid;
        List<ThemeTreeVO> treeVOList = this.context.excuteQuery(sql, ThemeTreeVO.class);
        List<DataTreeVO> dataTreeVOList = new ArrayList<>();
        for (ThemeTreeVO treeVO : treeVOList) {
            DataTreeVO dataTreeVO = new DataTreeVO();
            dataDTO.setType(treeVO.getId());
            dataTreeVO.setId(treeVO.getId());
            dataTreeVO.setThemename(treeVO.getThemename());
            dataTreeVO.setDataList(selectListByCondition(dataDTO));
            dataTreeVOList.add(dataTreeVO);
        }
        return dataTreeVOList;
    }

    public ChildThemeDataVO getSearchTreeData(DataDTO dataDTO) {
        ChildThemeDataVO childThemeDataVO = new ChildThemeDataVO();
        childThemeDataVO.setThemeTreeList(selectFirstThemeList());
        String type = Optional.ofNullable(dataDTO.getType()).orElse(childThemeDataVO.getThemeTreeList().get(0).getId());
        childThemeDataVO.setDataList(selectChildThemeDataList(dataDTO, type));
        return childThemeDataVO;
    }

    @Override
    public TextDataVO getTextDataById(String urlid) {
        String sql = "SELECT id,urlid,title,content,url,type,pubdate,website,keyword FROM TEXTDATAVIEW where urlid = " + urlid;
        return this.context.excuteQueryReturnOne(sql, TextDataVO.class);
    }

    /**
     * 遍历关键词keyword 模糊查询直到满足关联数
     */
    @Override
    public List<TextDataVO> getTextDataRelated(String urlid, Integer num) {
        List<TextDataVO> textDataVOList = new ArrayList<>();
        TextDataVO textDataVO = getTextDataById(urlid);
        if (ObjectUtils.isEmpty(textDataVO)) {
            return textDataVOList;
        }
        String[] keywords = textDataVO.getKeyword().split(";;");
        Integer count = 0;
        for (String str : keywords) {
            String sql = "SELECT id,urlid,title,content,url,type,pubdate,website from TEXTDATAVIEW where keyword %= " + str + " and not urlid = " + urlid;
            TextDataVO relatedVO = this.context.excuteQueryReturnOne(sql, TextDataVO.class);
            if (ObjectUtils.isEmpty(relatedVO)) {
                continue;
            }
            count++;
            textDataVOList.add(relatedVO);
            if (count.equals(num)) {
                break;
            }
        }
        return textDataVOList;
    }

}
